package org.simp.handler;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

import javax.security.auth.callback.Callback;

import org.apache.mina.core.session.IoSession;
import org.simp.common.Constants;
import org.simp.core.message.SimpMessage;
import org.simp.core.message.SimpMessageWraper;
import org.simp.core.request.SimpRequest;
import org.simp.core.request.SimpRequestWarper;
import org.simp.node.SimpClientConnector;
import org.simp.session.SimpSession;
import org.simp.session.SimpSessionWraper;

/**
 * @author zhuhaitao at 2014-5-23
 *
 * 客户端Handler，接收消息，处理或者转发
 */
public class SimpClientHandler extends AbstractSimpHandler  {

	protected SimpSession simpSession ;


	private Map<Integer,Response> responseMap = new HashMap<Integer,Response>();
	
	
	protected SimpSession getSession(IoSession session) {
		// TODO Auto-generated method stub
		return simpSession;
	}

	@Override
	public void sessionClosed(IoSession session) throws Exception {
		/**
		 * 掉线重连
		 */
		SimpClientConnector connector = (SimpClientConnector) context.getAttribute(Constants.NODE);
		connector.reConnect();
	}

	@Override
	public void sessionCreated(IoSession session) throws Exception {
		simpSession = new SimpSessionWraper(session);
	}

	@Override
	public void send(SimpMessage message) {
		/**发送消息，源地址域加一**/
		message.addSrcAddress(context.getContextName());
		message.decObjAddress(context.getContextName());
		simpSession.write(message);
	}

	/**
	 * 发送消息并等待60秒
	 * @param message
	 * @return
	 *  @Author zhuhaitao at 2014年6月25日
	 *
	 */
	public SimpRequest sendAndWaitResponse(SimpMessage message){
		return sendAndWaitResponse(message, 60);
	}
	/**
	 * 发送消息并等待seconds秒
	 * @param message
	 * @param seconds
	 * @return
	 *  @Author zhuhaitao at 2014年6月25日
	 *
	 */
	public SimpRequest sendAndWaitResponse(SimpMessage message,int seconds){
		send(message);
		Response response = new Response(message.getHead().getSerial());
		responseMap.put(message.getHead().getSerial(),response);
		
		try {
			return response.get(seconds, TimeUnit.SECONDS);
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (ExecutionException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (TimeoutException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}finally{
			responseMap.remove(message.getHead().getSerial());
		}
		return null;
	}
	@Override
	public SimpSession getSimpSession(long sessionId) {
		return simpSession;
	}

	@Override
	public SimpSession[] getSessionByName(String name) {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public SimpSession[] getSessionByType(String nodeType) {
		// TODO Auto-generated method stub
		return null;
	}
	
	
	@Override
	protected void receiveMessage(SimpRequest request) {
		/**如果有客户端等待响应的请求，将请求放入map**/
		Response response = responseMap.get(request.getHead().getSerial());
		if(response != null){
			response.set(request);
		}
	}


	private class Response extends FutureTask<SimpRequest>{
		private int serial;
		public Response(int serial) {
			super(new Callable<SimpRequest>() {
				
				public SimpRequest call(){
					return null;
				}
			});
			this.serial = serial;
		}
		@Override
		protected void set(SimpRequest v) {
			// TODO Auto-generated method stub
			super.set(v);
		}
		
		
	}
}
